﻿using System.Collections.Generic;
using Amazon.SQS;
using Amazon.SQS.Model;
using NUnit.Framework;
using Rhino.Mocks;
using ShuttleBus.Transports.AmazonSqs.Clients;

namespace Tests.Transports.AmazonSqs.SqsWrapperTests
{
    public partial class SqsWrapperTests
    {
        [TestFixture]
        public class WhenGettingQueueArn
        {
            private AmazonSQS _sqs;
            private SqsWrapper _wrapper;

            [SetUp]
            public void SetUp()
            {
                _sqs = MockRepository.GenerateMock<AmazonSQS>();
                _wrapper = new SqsWrapper(_sqs);
            }

            [TearDown]
            public void TearDown()
            {
                _sqs.VerifyAllExpectations();
            }

            [Test]
            public void Creates_Queue_If_Not_Exists()
            {
                var expectedQueueArn = "theQueueArn";
                var queueName = "queueName";
                var queueUrl = "https://queueurl";

                var createReponse = new CreateQueueResponse { CreateQueueResult = new CreateQueueResult { QueueUrl = queueUrl } };
                var attributeResponse = new SetQueueAttributesResponse();
                var attributesResponse = new GetQueueAttributesResponse
                                             {
                                                 GetQueueAttributesResult = new GetQueueAttributesResult
                                                                                {
                                                                                    Attribute = new List<Attribute>
                                                                                                    {
                                                                                                        new Attribute
                                                                                                            {
                                                                                                                Value =
                                                                                                                    expectedQueueArn
                                                                                                            }
                                                                                                    }
                                                                                }
                                             };

                _sqs.Expect(s => s.CreateQueue(Arg<CreateQueueRequest>.Matches(r => r.QueueName == queueName))).Return(createReponse);
                _sqs.Expect(s => s.SetQueueAttributes(Arg<SetQueueAttributesRequest>
                                                          .Matches(r => r.QueueUrl == queueUrl &&
                                                                        r.Attribute.Count == 1 &&
                                                                        r.Attribute[0].Name == "MaximumMessageSize" &&
                                                                        r.Attribute[0].Value == "65536")))
                    .Return(attributeResponse);
              
                _sqs.Expect(
                    s => s.GetQueueAttributes(Arg<GetQueueAttributesRequest>.Matches(r => r.AttributeName.Count == 1 &&
                                                                                          r.AttributeName[0] ==
                                                                                          "QueueArn" &&
                                                                                          r.QueueUrl ==
                                                                                          queueUrl)))
                    .Return(attributesResponse);

                var actual = _wrapper.GetQueueArn(queueName);

                Assert.AreEqual(expectedQueueArn, actual);

            }

            [Test]
            public void Creates_Queue_If_Not_Exists_Only_Once()
            {
                var expectedQueueArn = "theQueueArn";
                var queueName = "queueName";
                var queueUrl = "https://queueurl";

                var createReponse = new CreateQueueResponse { CreateQueueResult = new CreateQueueResult { QueueUrl = queueUrl } };
                var attributeResponse = new SetQueueAttributesResponse();
                var attributesResponse = new GetQueueAttributesResponse
                {
                    GetQueueAttributesResult = new GetQueueAttributesResult
                    {
                        Attribute = new List<Attribute>
                                                                                                    {
                                                                                                        new Attribute
                                                                                                            {
                                                                                                                Value =
                                                                                                                    expectedQueueArn
                                                                                                            }
                                                                                                    }
                    }
                };

                _sqs.Expect(s => s.CreateQueue(Arg<CreateQueueRequest>.Matches(r => r.QueueName == queueName))).Return(createReponse).Repeat.Once();
                _sqs.Expect(s => s.SetQueueAttributes(Arg<SetQueueAttributesRequest>
                                                          .Matches(r => r.QueueUrl == queueUrl &&
                                                                        r.Attribute.Count == 1 &&
                                                                        r.Attribute[0].Name == "MaximumMessageSize" &&
                                                                        r.Attribute[0].Value == "65536")))
                    .Return(attributeResponse).Repeat.Once();

                _sqs.Expect(
                    s => s.GetQueueAttributes(Arg<GetQueueAttributesRequest>.Matches(r => r.AttributeName.Count == 1 &&
                                                                                          r.AttributeName[0] ==
                                                                                          "QueueArn" &&
                                                                                          r.QueueUrl ==
                                                                                          queueUrl)))
                    .Return(attributesResponse).Repeat.Once();

                var actual = _wrapper.GetQueueArn(queueName);
                var actual2 = _wrapper.GetQueueArn(queueName);
                var actual3 = _wrapper.GetQueueArn(queueName);

                Assert.AreEqual(expectedQueueArn, actual);
                Assert.AreEqual(expectedQueueArn, actual2);
                Assert.AreEqual(expectedQueueArn, actual3);

            }
        }
    }
}